﻿using System;
using System.IO;
using System.Text;
using System.Windows.Forms;
using PodpisyElektorniczne.Classes;
using PodpisyElektorniczne.Interfaces;
using BI = System.Numerics.BigInteger;
using System.Diagnostics;

namespace PodpisyElektorniczne
{
    public partial class Form1 : Form
    {
        public static LoggedIn Log;
        private readonly string _toShow;
        
        public LoggedIn LogUeser { get { return Log; } set { Log = value; } }
        public static KeyPreferences KeyPrefs;
        public string[] FileData;
        private StepOutRingSignature _srs;
        public string OpenedFile;


        public Form1()
        {
            InitializeComponent();
            Log = Program.Log;
            KeyPrefs = KeyPreferences.ObjDeserializer() ?? new KeyPreferences();
            FileData = new string[2];

            OpenedFile = string.Empty;
            Settings.PrimeTrials = KeyPrefs.NoTrials;
            
            _toShow = String.Empty;
            txt_msgWin.Text = _toShow;
            tSS_LoggedUser.Text = string.Format("{0} {1} [{2}]",Log.Usser.Name,Log.Usser.Surname, Log.Usser.Login);


        }

        
        private void button1_Click(object sender, EventArgs e)
        {
            txt_log.Text = string.Format("{0}{1}", @"Text cleared.", Environment.NewLine) + txt_log.Text;
            txt_msgWin.Text = "";
            FileData[0] = string.Empty;
            FileData[1] = string.Empty;
            btn_signature.Enabled = false;
            btn_Confession.Enabled = false;
            btn_stepOut.Enabled = false;
            btn_verificationV.Enabled = false;
        }


        private void preferencesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txt_log.Text = string.Format("{0}{1}", @"Opening preferences...", Environment.NewLine) + txt_log.Text;
            var f = new frmSettings();
            f.MainForm = txt_log;
            f.Show();            
        }

        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var ab = new AboutRing();
            ab.ShowDialog();
            
            
            if(ab.AcceptButton.DialogResult == DialogResult.Cancel)
            {
                ab.Close();
                ab.Dispose();
            }

        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Program.Ll.Dispose();
        }

        private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            txt_log.Text = string.Format("{0}{1}", @"Closing program...", Environment.NewLine) + txt_log.Text;
            var res =
                MessageBox.Show(
                    @"If you generated an signature, you must not forget to save this key. Every data will be lost. Are you sure you wanto to quit ?",
                    @"Warning", MessageBoxButtons.YesNo);
            if(res == DialogResult.Yes) Close();
        }

        

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txt_log.Text = @"Loading message or signature file..." + Environment.NewLine + txt_log.Text;
            var oFileDialog = new OpenFileDialog();
            oFileDialog.Filter = @"txt files (*.txt)|*.txt|signature files files (*.sig)| *.sig";
            var result = oFileDialog.ShowDialog();
            string line;
            try
            {
                if (result == DialogResult.OK)
                {
                    FileData[0] = oFileDialog.FileName;
                    var p = oFileDialog.FileName.Split('.');
                    switch(p[p.Length-1])
                    {
                        case "sig":
                            if(_srs == null) _srs = new StepOutRingSignature();
                           
                            _srs = StepOutRingSignature.GetStoredSRSignature(FileData[0]);
                                    
                            
                            btn_signature.Enabled = false;
                            btn_verificationV.Enabled = true;
                            btn_Confession.Enabled = true;
                            btn_stepOut.Enabled = true;
                            txt_log.Text = @"Signature file has been loaded successfuly." + Environment.NewLine + txt_log.Text;
                            break;
                        default:
                            using (var str = new StreamReader(FileData[0],Encoding.UTF8))
                            {
                                while ((line = str.ReadLine()) != null)
                                {
                                    FileData[1] += line + Environment.NewLine;
                                }
                                txt_msgWin.Text = string.Empty;
                                txt_msgWin.Text = FileData[1];  
                        
                            }
                            txt_log.Text = string.Format("{0}{1}{2}", "Message file has been loaded successfuly.", Environment.NewLine, txt_log.Text);
                            btn_signature.Enabled = true;
                            btn_verificationV.Enabled = false;
                            btn_Confession.Enabled = false;
                            btn_stepOut.Enabled = false;
                            break;
                    }
                }
                oFileDialog.Dispose();
            }catch(Exception ex)
            {
                txt_log.Text = string.Format("{0}{1}{2}{3}","ERROR: ",ex.Message,Environment.NewLine,txt_log.Text);
                MessageBox.Show(@"Selected file could not be load. Try another file.", @"Error", MessageBoxButtons.OK);
            }

        }

        private void btn_signature_Click(object sender, EventArgs e)
        {
            var settings = (new SchemaSetts(Program.Log.Usser.Login)).XmlDeserializeSchemaProperties();
            txt_log.Text = string.Format("{0}{1}{2}", @"Signing the message...", Environment.NewLine,txt_log.Text);
            if(settings.SecretR ==-1 && settings.SecretRj ==-1)
            {
                txt_log.Text = string.Format("{0}{1}{2}", @"There are no secrets generated. Open tools -> Performance and generate some secrets.", Environment.NewLine, txt_log.Text);
                MessageBox.Show(
                    @"There are no secrets generated. Open tools -> Performance and generate some secrets.", @"Error",
                    MessageBoxButtons.OK);
            }
            try
            {
                if(FileData[1] == string.Empty)
                {
                    txt_log.Text = @"No message has been found. Load a message file first." + Environment.NewLine + txt_log.Text;
                    throw new Exception(@"No message has been found. Load a message file first.");

                }
                switch(KeyPrefs.IsRandom)
                {
                    case true:
                        _srs = new StepOutRingSignature(KeyPrefs.NoMembers, FileData[1]);
                        break;
                    default:
                        _srs = new StepOutRingSignature(FileData[1]);
                        break;
                }
                
                if (!_srs.isPubPrivGen) throw new Exception(@"There is no key for this user. Generate keys before signing message.");
                Stopwatch sw = new Stopwatch();
                sw.Start();
                if (_srs.SRSignature())
                {
                    sw.Stop();
                    txt_log.Text += "SIGNATURE ------------------------> " + sw.ElapsedMilliseconds + "[ms]";
                    txt_msgWin.Text += string.Format("{0}{1}{2}{3}", @"-----------SIGNATURE------------",
                                                     Environment.NewLine,
                                                     _srs.Sign, Environment.NewLine);
                    txt_log.Text =
                        string.Format("{0}{1}", @"Signature has been created successfuly.", Environment.NewLine) +
                        txt_log.Text;
                    btn_verificationV.Enabled = true;
                    btn_Confession.Enabled = true;
                    btn_stepOut.Enabled = true;
                }
            }
            catch(Exception)
            {
                txt_log.Text = string.Format("{0}{1}",
                                              @"There is a problem with signing this message. Try again.", Environment.NewLine) + txt_log.Text;
                MessageBox.Show(@"There is a problem with signing this message. Try again.", @"Error",
                                MessageBoxButtons.OK);
            }
        }

        private void txt_log_TextChanged(object sender, EventArgs e)
        {
            txt_log.ScrollToCaret();
        }
        
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txt_log.Text += string.Format("{0}{1}", @"Saving signature...", Environment.NewLine);
            var saveDialog = new SaveFileDialog();
            saveDialog.Filter = @"signature files (*.sig)|*.sig";
            var result =saveDialog.ShowDialog();
            try
            {
                if (result == DialogResult.OK)
                {
                    if (saveDialog.FileName != string.Empty)
                    {
                        var stf = saveDialog.FileName;
                        saveDialog.Dispose();
                        if (_srs.StoreSRSignature(stf))
                            txt_log.Text = string.Format("{0}{1}", @"Signature saved successfuly.", Environment.NewLine) + txt_log.Text;
                    }
                }
            }catch(Exception ex)
            {
                txt_log.Text = string.Format("{0}{1}", @"Signature didn't save successfuly, try again.", Environment.NewLine) + txt_log.Text;
                MessageBox.Show(@"Problem with saving signature. " + ex.Message);
                
            }
        }

        private void saveKeyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            txt_log.Text = string.Format("{0}{1}", @"Saving message...", Environment.NewLine) + txt_log.Text;
            var saveDialog = new SaveFileDialog { Filter = @"txt files (*.txt)|*.txt" };
            var result = saveDialog.ShowDialog();
            try
            {
                if (result == DialogResult.OK)
                {
                    if (saveDialog.FileName != string.Empty)
                    {
                        var stf = saveDialog.FileName;
                        saveDialog.Dispose();
                        using (var writer = new StreamWriter(stf, false, Encoding.UTF8))
                        {
                            writer.WriteLine(txt_msgWin.Text);
                        }
                        //TO DO: 15-11-2011
                        //Serializacja podpisu do zadanej lokalizacji: srs.XmlSerialization(stf);
                        txt_log.Text = string.Format("{0}{1}", @"Message saved successfuly. Localization: " + stf,
                                                      Environment.NewLine) + txt_log.Text;
                    }
                }
            }catch(Exception ex)
            {
                MessageBox.Show(string.Format("{0}{1}{2}", ex.Message, Environment.NewLine, ex.InnerException),@"Error",MessageBoxButtons.OK);
                txt_log.Text = string.Format("{0}{1}", @"Message didn't save successfully, try again.", Environment.NewLine) + txt_log.Text;
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (FileData[0] != string.Empty)
                {
                    using (var write = new StreamWriter(FileData[0],false,Encoding.UTF8))
                    {
                        write.Write(txt_msgWin.Text);
                    }
                    txt_log.Text += string.Format("{0}{1}", @"Message saved successfuly.", Environment.NewLine);
                }

            }
            catch (Exception ex)
            {
                txt_log.Text += string.Format("{0}{1}", @"Problem with saving the message. Please try again.",
                                             Environment.NewLine);
                MessageBox.Show(@"Problem with saving the message. Please try again. "+Environment.NewLine + ex.Message,@"Error",MessageBoxButtons.OK);
            }
        }

        private void btn_verificationV_Click(object sender, EventArgs e)
        {
            try
            {
                if (_srs == null)
                {
                    btn_verificationV.Enabled = false; 
                    return; 
                }
                Stopwatch sw = new Stopwatch();
                sw.Start();
                var settings = (new SchemaSetts(Program.Log.Usser.Login)).XmlDeserializeSchemaProperties();
                //bool trolu = 
                if (_srs.VerificationSrs() || _srs.VerificationSrs(_srs._sign, settings.SubOrderQ))
                {
                    sw.Stop();
                    txt_log.Text += "Verification --------------------------> "+sw.ElapsedMilliseconds +"[ms]";
                    MessageBox.Show(@"You've signed this message. Signature is valid for your public key.", @"Verification", MessageBoxButtons.OK);
                    return;
                }
                sw.Stop();
                txt_log.Text += "Verification --------------------------> " + sw.ElapsedMilliseconds + "[ms]";
                MessageBox.Show(@"You've not signed this message. Signature is not valid for your public key.", @"Verification", MessageBoxButtons.OK);               
            }
            catch(Exception ex)
            {
                txt_log.Text += string.Format("{0}{1}", @"Problem with saving the message. Please try again.",
                             Environment.NewLine);
                MessageBox.Show(@"Problem with verifing the signature. Please try again. " + Environment.NewLine + ex.Message, @"Error", MessageBoxButtons.OK);

            }
        }

        private void btn_Confession_Click(object sender, EventArgs e)
        {
            try
            {
                if (_srs == null) return;
                if (_srs.ConfessionSrs())
                {
                    MessageBox.Show(@"You are trully the signer of this message. Signature is valid for your public key.",
                                    @"Confession", MessageBoxButtons.OK);
                    return;
                }
                MessageBox.Show(@"You are trully the cheater. Signature is invalid for your public key.",
                                    @"Confession", MessageBoxButtons.OK);
            }catch(Exception ex)
            {
                txt_log.Text += string.Format("{0}{1}", @"Problem with signer's confession.",
                             Environment.NewLine);
                MessageBox.Show(@"Problem with signer's confession. Please try again. " + Environment.NewLine + ex.Message, @"Error", MessageBoxButtons.OK);
            }

        }

        private void btn_stepOut_Click(object sender, EventArgs e)
        {
            try
            {
                if (_srs == null)
                {
                    MessageBox.Show(@"Load the signature again. It is empty for sure.");
                    return;
                }
                if(!_srs.SetpOutSrs())
                {
                    MessageBox.Show(@"You are lucky one. You didn't sign this message. Step out successful.",
                                    @"Setp Out", MessageBoxButtons.OK);
                    return;
                }
                MessageBox.Show(@"You are the cheater. You did sign this message. Step out failed.",
                                    @"Setp Out", MessageBoxButtons.OK);
            }
            catch (Exception ex)
            {
                txt_log.Text += string.Format("{0}{1}", @"Problem with signer's step out procedure.",
                             Environment.NewLine);
                MessageBox.Show(@"Problem with signer's step out. Please try again. " + Environment.NewLine + ex.Message, @"Error", MessageBoxButtons.OK);
                
            }
        }
        
    }
}
